﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Http;
using MuXue.Zyiz.Template.Domain.Model;
using MuXue.Zyiz.Template.Common;
using System.Diagnostics;

namespace MuXue.Zyiz.Template.WebApi.Filter
{
    /// <summary>
    /// 记录日志用过滤器
    /// </summary>
    public class LogstashFilter : IActionFilter, IResultFilter
    {
        private string ActionArguments { get; set; }

        /// <summary>
        /// 请求体中的所有值
        /// </summary>
        private string RequestBody { get; set; }
        private Stopwatch Stopwatch { get; set; }

        private ILogger _logger;
      
        public LogstashFilter(ILogger<LogstashFilter> logger )
        {
            _logger = logger;
            
        }

        /// <summary>
        /// Action 调用前执行
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutingContext context)
        {
              
            long contentLen = context.HttpContext.Request.ContentLength == null ? 0 : context.HttpContext.Request.ContentLength.Value;
            if (contentLen > 0)
            {
                // 读取请求体中所有内容
                System.IO.Stream stream = context.HttpContext.Request.Body;
                if (context.HttpContext.Request.Method == "POST")
                {
                    stream.Position = 0;
                }
                byte[] buffer = new byte[contentLen];
                stream.Read(buffer, 0, buffer.Length);

                RequestBody = System.Text.Encoding.UTF8.GetString(buffer);// 转化为字符串
            }

            ActionArguments = JsonConvert.SerializeObject(context.ActionArguments);

            Stopwatch = new Stopwatch();
            Stopwatch.Start();


            string url = context.HttpContext.Request.Host + context.HttpContext.Request.Path + context.HttpContext.Request.QueryString;
            string method = context.HttpContext.Request.Method;
           
            _logger.LogInformation($"地址：{url} \n " +
               $"方式：{method} \n " +
               $"请求体：{RequestBody} \n " +
               $"完整参数：{ActionArguments}\n " );


        }

        /// <summary>
        /// Action 方法调用后，Result 方法调用前执行
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuted(ActionExecutedContext context)
        {
            // do nothing
        }

        /// <summary>
        /// Result 方法调用前（View 呈现前）执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuting(ResultExecutingContext context)
        {
            // do nothing
        }

        /// <summary>
        /// Result 方法调用后执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuted(ResultExecutedContext context)
        {

            Stopwatch.Stop();
            string url = context.HttpContext.Request.Host + context.HttpContext.Request.Path + context.HttpContext.Request.QueryString;
                string method = context.HttpContext.Request.Method;
                string qs = ActionArguments;
                string res = "在返回结果前发生了异常";
                if (context.Result is ObjectResult)
                {
                    dynamic result = context.Result.GetType().Name == "EmptyResult" ? new { Value = "无返回结果" } : context.Result as dynamic;
                    if (result != null)
                    {
                        res = JsonConvert.SerializeObject(result.Value);
                    }

                }

                _logger.LogInformation($"地址：{url} \n " +
                    $"方式：{method} \n " +
                    $"请求体：{RequestBody} \n " +
                    $"参数：{qs}\n " +
                    $"结果：{res}\n " +
                    $"耗时：{Stopwatch.Elapsed.TotalMilliseconds} 毫秒");

            
        }
    }
}
